package com.ai.module.mj.service.impl.translate;


import cn.hutool.core.exceptions.ValidateException;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.digest.MD5;
import com.ai.module.chat.util.SpringUtils;
import com.ai.module.mj.config.propertites.YmlProperties;
import com.ai.module.mj.constant.enums.TranslateWay;
import com.ai.module.mj.service.TranslateService;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.support.BeanDefinitionValidationException;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class BaiduTranslateServiceImpl implements TranslateService {
	private static final String TRANSLATE_API = "https://fanyi-api.baidu.com/api/trans/vip/translate";

	private final String appid;
	private final String appSecret;

	public BaiduTranslateServiceImpl(YmlProperties.BaiduTranslateConfig translateConfig) {
		this.appid = translateConfig.getAppid();
		this.appSecret = translateConfig.getAppSecret();
		if (!CharSequenceUtil.isAllNotBlank(this.appid, this.appSecret)) {
			throw new BeanDefinitionValidationException("mj.baidu-translate.appid或mj.baidu-translate.app-secret未配置");
		}
	}

	@Override
	public String translateToEnglish(String prompt) {
		if (!containsChinese(prompt)) {
			return prompt;
		}
		return realTranslateTo(prompt,"en","zh");
	}
	@Override
	public String translateToChinese(String prompt) {
		if (!containsEnglish(prompt)) {
			return prompt;
		}
		return realTranslateTo(prompt,"zh","en");
	}
	public String realTranslateTo(String prompt,String to,String from){
		String salt = RandomUtil.randomNumbers(5);
		String sign = MD5.create().digestHex(this.appid + prompt + salt + this.appSecret);
		HttpHeaders headers = new HttpHeaders();
		headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
		MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
		body.add("from", from);
		body.add("to", to);
		body.add("appid", this.appid);
		body.add("salt", salt);
		body.add("q", prompt);
		body.add("sign", sign);
		HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(body, headers);
		try {
			ResponseEntity<String> responseEntity = new RestTemplate().exchange(TRANSLATE_API, HttpMethod.POST, requestEntity, String.class);
			if (responseEntity.getStatusCode() != HttpStatus.OK || CharSequenceUtil.isBlank(responseEntity.getBody())) {
				throw new ValidateException(responseEntity.getStatusCodeValue() + " - " + responseEntity.getBody());
			}
			JSONObject result = new JSONObject(responseEntity.getBody());
			if (result.has("error_code")) {
				throw new ValidateException(result.getString("error_code") + " - " + result.getString("error_msg"));
			}
			List<String> strings = new ArrayList<>();
			JSONArray transResult = result.getJSONArray("trans_result");
			for (int i = 0; i < transResult.length(); i++) {
				strings.add(transResult.getJSONObject(i).getString("dst"));
			}
			return CharSequenceUtil.join("\n", strings);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("调用百度翻译失败: {}", e.getMessage());
		}
		return prompt;
	}


	@Override
	public String commonTranslatePromptEn(String prompt) {
		 YmlProperties properties= SpringUtils.getClazz(YmlProperties.class);
		if (TranslateWay.NULL.equals( properties.getTranslateWay()) || CharSequenceUtil.isBlank(prompt)) {
			return prompt;
		}
		List<String> imageUrls = new ArrayList<>();
		Matcher imageMatcher = Pattern.compile("https?://[a-z0-9-_:@&?=+,.!/~*'%$]+\\x20+", Pattern.CASE_INSENSITIVE).matcher(prompt);
		while (imageMatcher.find()) {
			imageUrls.add(imageMatcher.group(0));
		}
		String paramStr = "";
		Matcher paramMatcher = Pattern.compile("\\x20+-{1,2}[a-z]+.*$", Pattern.CASE_INSENSITIVE).matcher(prompt);
		if (paramMatcher.find()) {
			paramStr = paramMatcher.group(0);
		}
		String imageStr = CharSequenceUtil.join("", imageUrls);
		String text = prompt.substring(imageStr.length(), prompt.length() - paramStr.length());

		if (CharSequenceUtil.isNotBlank(text)) {
			text =  translateToEnglish(text).trim();
		}
		return imageStr + text + paramStr;
	}


}
